
package com.feib.ebilling.job;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.feib.ebilling.job.service.BillFeedbackService;
import com.feib.ebilling.job.service.FtpService;

/**
 * @title (#)BillFeedback.java<br>
 * @description 銷帳資料批次回饋給帳單業者<br>
 * @author Yaude Huang<br>
 * @version 1.0.0 2011/06/03
 * @copyright Far Eastern International Bank Copyright (c) 2011<br>
 * @2011/06/03 create by Yaude Huang<br>
 */
@Service("billFeedback")
public class BillFeedback {

    public static Logger logger = LoggerFactory.getLogger(BillFeedback.class);

    public static final SimpleDateFormat BASIC_DATE_TIME_FORMAT = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

    @Resource(name="billFeedbackService")
    private BillFeedbackService billFeedbackService;
   
    @Resource(name="ftpService")
    private FtpService ftpService;
   
    public static List<String> APP_GROUP;
    static
    {
    	APP_GROUP = new ArrayList<String>();    	
    }
    /**
     * 銷帳資料批次回饋
     * @param args array, args[0]指定帳單業者  args[1]西元日期<br>
     */
    public static void main(String[] args) {
        
        /* 傳輸日期 --> 銷帳日期當日 */
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date dNow = new Date();
        /* 銷帳日期前一日，換日時有可能有交易，所以要再跑一兩次，確認資料皆已回饋 */
        long t = dNow.getTime();
        t -= 24*60*60*1000; 
        Date then = new Date(t);
        String preProcessDate = dateFormat.format(then);
         
        String processDate = dateFormat.format(dNow); 
        if (null == args || 0 == args.length)
        {
        	/* 處理系統日當日所有帳單業者回饋檔案 */
        	// do nothing.  
        	// processDate = "20110414";
        }
        else
        {
            /* 指定帳單業者 */
            if (1 == args.length)
            {
            	APP_GROUP.add(args[0]);
                /* 指定通路，系統日 */
            }
            else
            {
            	if (2 == args.length){
                    /* 指定帳單業者[0]，指定日期參數[1]*/
            		APP_GROUP.add(args[0]);
                    processDate = args[1];
                }	
            }
        }
        
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                        new String[] {"applicationContext-config.xml", "applicationContext-dao.xml", "applicationContext-properties.xml"});
        
        Date start = new Date();
        logger.info("[開始] 帳單業者銷帳回饋檔  - {}", BASIC_DATE_TIME_FORMAT.format(start));
        try {
        	/* 取得交易物件 */
        	BillFeedback billFeedback = (BillFeedback)ctx.getBean("billFeedback");
        	/* 載入帳單業者代碼 */
        	billFeedback.getGroup();
        	/* 依日期產生檔案 */
        	billFeedback.doProcessDate(processDate);        	
        	dateFormat = new SimpleDateFormat("HHmmss");  
        	/* 每日00:00:00 ~ 00:30:00 前一日銷帳檔再產生一次  */
        	if (Integer.parseInt(dateFormat.format(dNow)) >= 0  &&  Integer.parseInt(dateFormat.format(dNow)) <= 3000){
        		logger.info("換日銷帳回饋檔再處理一次  - {}", dateFormat.format(dNow));
        	    billFeedback.doProcessDate(preProcessDate);
        	}    
        }
        catch (Exception e) {
            logger.error("[錯誤]" + e.getMessage(), e);
        }
        finally{
            Date end = new Date();
            logger.info("[結束] 帳單業者銷帳回饋檔  - {}", BASIC_DATE_TIME_FORMAT.format(start));
            logger.info("共費時 - " + ((end.getTime() - start.getTime()) / 1000) + " 秒");
        }
    }
    
    public void doProcessDate(String processDate) throws Exception{
    	/* 產生銷帳檔案 */
        int i = 0;
        for (String group : APP_GROUP){
            try {
            	logger.info("{}.{}", i + 1, group);
            	execute((String) APP_GROUP.get(i), processDate);
            	i++;            	
            }catch (Exception e) {
                Object[] objs = new Object[]{APP_GROUP.get(i), processDate};
                logger.error("[錯誤] 帳單業者:{}, 日期:{}, 回饋錯誤！", objs);
                logger.error("[錯誤]" + e.toString(), e);
            }
        }   
    }
    
    public void getGroup() throws Exception
    {
    	if (APP_GROUP == null || APP_GROUP.size() == 0){
        	List<Map<String, Object>> groups = this.billFeedbackService.loadGroups();
        	for(Map<String, Object> group : groups) {
        		logger.info("載入帳單業者代碼：" + (String) group.get("GROUP_NO"));
        		APP_GROUP.add((String) group.get("GROUP_NO"));
            }
        }
    }

    public void execute(String groupNo, String processDate) throws IOException
    {
        Assert.notNull(groupNo, "[錯誤]帳單業者 can't be null.");
        Assert.notNull(processDate, "[錯誤]傳輸日期  can't be null.");
        
        logger.info("************************************************");
        logger.info("帳單業者：{}", groupNo);
        logger.info("傳輸日期：{}", processDate);
        List<Map<String, Object>> groups = this.billFeedbackService.loadGroupPK(groupNo);        
        if (0 != groups.size())
        {  
        	Map<String, Object> group = groups.get(0);  
        	BigDecimal bd = (BigDecimal)group.get("GROUP_PK");   
        	String sContent = "";
        	int iType = (Integer) group.get("GROUP_TYPE");
        	if  (iType == 2){
        		logger.info("帳單類別：學校");
        		/* 學校銷帳檔格式 */
        	    sContent = this.billFeedbackService.writeContentSchool(groupNo, bd.toString(), processDate);
        	    /* 上傳資料 */
            	ftpService.putFTPFile(groupNo, processDate, sContent, groupNo + "." + processDate);            	
        	}else if  (iType == 3){
        		logger.info("帳單類別：管委會及一般代收");
        		/* 管委會及一般代收銷帳檔格式 */
        	    sContent = this.billFeedbackService.writeContentGeneral(groupNo, bd.toString(), processDate);
        	    /* 上傳資料 */
            	ftpService.putFTPFile(groupNo, processDate, sContent, groupNo + "." + processDate);
        	}else if  (iType == 4){	
        		logger.info("車貸策略聯盟回饋檔格式為客制化!" );
        	}else{
        	    logger.info("帳單類別：其他尚未上線" );
        	}
        }
    }
}
